package redis

import (
	"errors"
	"math"
	"strconv"
	"time"

	"github.com/go-redis/redis"
	"go.uber.org/zap"
)

const (
	oneWeekInSeconds = 7 * 24 * 3600
	scorePerVote     = 432
)

var (
	ErrVoteTimeExpire = errors.New("超出投票时间")
	ErrVoteRepeted    = errors.New("重复投票")
)

func PostVote(userid, postID string, value float64) (err error) {
	postTime := Client.ZScore(KeyPostTimeZSet, postID).Val()
	if float64(time.Now().Unix())-postTime > oneWeekInSeconds {
		return ErrVoteTimeExpire
	}
	//查询用户给当前帖子的投票记录
	ov := Client.ZScore(KeyPostVotedZSetPre+postID, userid).Val()

	if value == ov {
		return ErrVoteRepeted
	}
	var dir float64
	if value > ov {
		dir = 1
	} else {
		dir = -1
	}
	diff := math.Abs(ov - value)
	pipeline := Client.TxPipeline()

	pipeline.ZIncrBy(KeyPostScoreZSet, dir*diff*scorePerVote, postID).Result()

	if value == 0 {
		pipeline.ZRem(KeyPostVotedZSetPre+postID, userid)
	} else {
		pipeline.ZAdd(KeyPostVotedZSetPre+postID, redis.Z{
			Score:  value,
			Member: userid,
		})
	}
	_, err = pipeline.Exec()
	return
}

func CreatePost(postid, communityID int64) error {
	pipeline := Client.TxPipeline()
	pipeline.ZAdd(KeyPostTimeZSet, redis.Z{
		Score:  float64(time.Now().Unix()),
		Member: postid,
	})

	pipeline.ZAdd(KeyPostScoreZSet, redis.Z{
		Score:  float64(time.Now().Unix()),
		Member: postid,
	})

	cKey := KeyCommunitySetPre + strconv.Itoa(int(communityID))
	pipeline.SAdd(cKey, postid)

	_, err := pipeline.Exec()
	if err != nil {
		zap.L().Error("Client.ZAdd failed", zap.Error(err))

	}
	return nil
}
